﻿using System.Collections.Generic;
using System.Collections.ObjectModel;
using System;
using System.Diagnostics.CodeAnalysis;
using System.Text;
namespace TVersityDotNet.HelperTypes
{
    /// <summary>
    /// Enumeration of the different MediaSource Types
    /// </summary>
    public enum MediaSourceType
    {
        File, Folder, AudioUrl, VideoUrl, ImageUrl, AudioFeed, VideoFeed, ImageFeed, BadType
    }      

    public class MediaSource
    {
        /// <summary>
        /// The ID of the media source
        /// </summary>
        public int Id
        {
            get { return int.Parse(this.PropertyBag.GetPropertyFromPropertyBag("id")); }
            set { this.PropertyBag.AddPropertyToPropertyBag("id", value.ToString()); }
        }

        /// <summary>
        /// The URL of the media source
        /// </summary>
        public string Url
        {
            get { return this.PropertyBag.GetPropertyFromPropertyBag("url"); }
            set { this.PropertyBag.AddPropertyToPropertyBag("url", value); }
        }

        /// <summary>
        /// The type of the media source. <see cref="MediaSourceTypes">MediaSourceTypes</see>
        /// </summary>
        public MediaSourceType MSType
        {
            get { return (MediaSourceType)Enum.Parse(typeof(MediaSourceType), (string)this.PropertyBag.GetPropertyFromPropertyBag("mstype"), true); }
            set { this.PropertyBag.AddPropertyToPropertyBag("mstype", Enum.GetName(typeof(MediaSourceType), value).ToLowerInvariant()); }
        }

        /// <summary>
        /// The name of the media source.
        /// </summary>
        public string Name
        {
            get { return this.PropertyBag.GetPropertyFromPropertyBag("name"); }
            set { this.PropertyBag.AddPropertyToPropertyBag("name", value); }
        }

        /// <summary>
        /// The tags to associate with it
        /// </summary>
        [SuppressMessageAttribute("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
        public Collection<string> Tags
        {
            get { return new Collection<string>(new List<string>(this.PropertyBag.GetPropertyFromPropertyBag("tags").Split(new char[] { ';' }))); }
            set 
            {
                if (value.Count > 0)
                {
                    StringBuilder sb = new StringBuilder();
                    foreach (string tag in value)
                    {
                        sb.Append(string.Concat(tag, ";"));
                    }

                    this.PropertyBag.AddPropertyToPropertyBag("tags", sb.ToString());
                }
            }
        }                    

        /// <summary>
        /// A boolean value indicating if to look for audio items or not when processing the media source
        /// </summary>
        public bool LookForAudio 
        {
            get { return bool.Parse(this.PropertyBag.GetPropertyFromPropertyBag("lookforaudio")); }
            set { this.PropertyBag.AddPropertyToPropertyBag("lookforaudio", value.ToString()); }

        }

        /// <summary>
        /// A boolean value indicating if to look for video items or not when processing the media source
        /// </summary>
        public bool LookForVideo
        {
            get { return bool.Parse(this.PropertyBag.GetPropertyFromPropertyBag("lookforvideo")); }
            set { this.PropertyBag.AddPropertyToPropertyBag("lookforvideo", value.ToString()); }
        }

        /// <summary>
        /// A boolean value indicating if to look for photo items or not when processing the media source
        /// </summary>
        public bool LookForPhoto
        {
            get { return bool.Parse(this.PropertyBag.GetPropertyFromPropertyBag("lookforphoto")); }
            set { this.PropertyBag.AddPropertyToPropertyBag("lookforphoto", value.ToString()); }
        }

        /// <summary>
        /// A boolean value indicating if the media source is public and hence can be sent to a global respository for sharing with others
        /// </summary>
        public bool Public
        {
            get { return bool.Parse(this.PropertyBag.GetPropertyFromPropertyBag("public")); }
            set { this.PropertyBag.AddPropertyToPropertyBag("public", value.ToString()); }
        }

        /// <summary>
        /// Constructor for MediaSource
        /// </summary>
        /// <param name="id">MediaSouce's Id</param>
        /// <param name="url">MediaSouce's Url</param>
        /// <param name="type">MediaSouce's Type</param>
        /// <param name="name">MediaSouce's Name</param>
        /// <param name="tags">MediaSouce's Tags</param>
        public MediaSource(int id, string url, MediaSourceType type, string name, Collection<string> tags, bool isPublic)
        {
            this.PropertyBag = new PropertyBag();
            this.Id = id;
            this.Url = url;
            this.MSType = type;
            this.Name = name;
            this.Tags = tags;
            this.Public = isPublic;
        }

        /// <summary>
        /// Empty constructor for MediaSource
        /// </summary>
        public MediaSource()
        {
            this.PropertyBag = new PropertyBag();
            this.Tags = new Collection<string>();
            this.Public = true;
        }

        /// <summary>
        /// Returns the string value of the <see cref="MediaSourceTypes">MediaSourceTypes</see>
        /// </summary>
        /// <param name="mediaType">The media type to return the name for</param>
        /// <returns>The string value of the specific media type</returns>
        public static string GetMediaTypeName(MediaSourceType mediaType)
        {
            switch (mediaType)
            {
                case MediaSourceType.AudioFeed:
                    return "Audfeed";
                case MediaSourceType.AudioUrl:
                    return "Audurl";
                case MediaSourceType.File:
                    return "File";
                case MediaSourceType.Folder:
                    return "Folder";
                case MediaSourceType.ImageFeed:
                    return "Imgfeed";
                case MediaSourceType.ImageUrl:
                    return "Imgurl";
                case MediaSourceType.VideoFeed:
                    return "Vidfeed";
                case MediaSourceType.VideoUrl:
                    return "Vidurl";
                case MediaSourceType.BadType :
                    return "BADTYPE";
                default:
                    return "ERROR";
            }
        }

        /// <summary>
        /// Returns the MediaSourceType base on its name
        /// </summary>
        /// <param name="mediaTypeName">The name of the mediasource (based on TVersity's naming)</param>
        /// <returns>The media source associated with the name, or a BadType if it can't be found</returns>
        public static MediaSourceType GetMediaTypeByName(string mediaTypeName)
        {
            if (!string.IsNullOrEmpty(mediaTypeName))
            {
                switch (mediaTypeName.ToUpperInvariant())
                {
                    case "Audfeed":
                        return MediaSourceType.AudioFeed;
                    case "Audurl":
                        return MediaSourceType.AudioUrl;
                    case "File":
                        return MediaSourceType.File;
                    case "Folder":
                        return MediaSourceType.Folder;
                    case "Imgfeed":
                        return MediaSourceType.ImageFeed;
                    case "Imgurl":
                        return MediaSourceType.ImageUrl;
                    case "Vidfeed":
                        return MediaSourceType.VideoFeed;
                    case "Vidurl":
                        return MediaSourceType.VideoUrl;
                    default:
                        return MediaSourceType.BadType;
                }
            }
            else
                return MediaSourceType.BadType;
        }

        /// <summary>
        /// Returns the name of this mediasource
        /// </summary>
        /// <returns>Name of the mediasource</returns>
        public override string ToString()
        {
            return this.Name;
        }

        private PropertyBag _propertyBag;
        /// <summary>
        /// A dictionary representing the list of properties that are set. If anything isn't set, the defaults will be used
        /// </summary>
        public PropertyBag PropertyBag
        {
            get
            {
                if (this._propertyBag == null)
                    this._propertyBag = new PropertyBag();
                return this._propertyBag;
            }
            private set
            {
                this._propertyBag = value;
            }
        }        
    }
}
